<template>
  <div>
    <a-spin :spinning="spinning !== 0">
      <!-- 头部插槽 -->
      <component
        ref="header"
        v-if="header.show"
        :is="header.componentFile"
        :stores="stores"
      />

      <!-- 查询区域 -->
      <div class="table-page-search-wrapper" v-if="queryColumns.length > 0 || (isFlow && flowScope!=='noLimit')">
        <a-form layout="horizontal" @keyup.enter.native="searchQuery">
          <a-row :gutter="8">
            <a-col :span="6" v-if="isFlow && flowScope!=='noLimit'">
              <a-form-item :label="$t('m.bpm.entity.myInstanceClassify')" v-if="flowScope === 'all'" :labelCol="labelCol" :wrapperCol="wrapperCol">
                <a-select v-model="myInstanceClassify" placeholder="">
                  <a-select-option value="all">{{this.$t('m.common.label.all')}}</a-select-option>
                  <a-select-option value="noRun">{{ $t('m.eform.formDesign.label.wei-qi-dong') }}</a-select-option>
                  <a-select-option value="run">{{ $t('m.eform.formDesign.label.liu-zhuan-zhong') }}</a-select-option>
                  <a-select-option value="end">{{ $t('m.eform.formDesign.label.yi-jie-shu') }}</a-select-option>
                  <a-select-option value="start">{{ $t('m.eform.formDesign.label.wo-fa-qi') }}</a-select-option>
                </a-select>
              </a-form-item>
              <a-form-item :label="$t('m.eform.formDesign.label.ren-wu-zhuang-tai')" v-else-if="flowScope==='myTask'" :labelCol="labelCol" :wrapperCol="wrapperCol">
                <a-select v-model="myInstanceClassify" :placeholder="$t('m.eform.formDesign.label.ren-wu-zhuang-tai')">
                  <a-select-option value="all">{{this.$t('m.common.label.all')}}</a-select-option>
                  <a-select-option value="todo">{{$t('m.bpm.other.option_todo')}}</a-select-option>
                  <a-select-option value="done">{{$t('m.bpm.other.option_todoed')}}</a-select-option>
                </a-select>
              </a-form-item>
              <a-form-item :label="$t('m.bpm.entity.myInstanceClassify')" v-else :labelCol="labelCol" :wrapperCol="wrapperCol">
                <a-select v-model="myInstanceClassify" placeholder="">
                  <a-select-option value="all">{{this.$t('m.common.label.all')}}</a-select-option>
                  <a-select-option value="noRun">{{ $t('m.eform.formDesign.label.wei-qi-dong') }}</a-select-option>
                  <a-select-option value="allFlow">{{ $t('m.eform.formDesign.label.wo-fa-qi') }}&{{ $t('m.eform.formDesign.label.wo-can-yu') }}</a-select-option>
                  <a-select-option value="start">{{ $t('m.eform.formDesign.label.wo-fa-qi') }}</a-select-option>
                  <a-select-option value="participate">{{ $t('m.eform.formDesign.label.wo-can-yu') }}</a-select-option>
                </a-select>
              </a-form-item>
            </a-col>
            <a-col v-for="(query, index) in queryColumns" :key="query.colCode"
                   :span="query.queryFormatJson.compColSpan || 6"
                   v-if="query.queryIsHidden !== 'Y'">
              <a-form-item :label="$locale(query.queryAlias || query.colName)" :labelCol="typeof query.queryFormatJson.labelColSpan !== 'undefined' ? {span: query.queryFormatJson.labelColSpan} : labelCol" :wrapperCol="typeof query.queryFormatJson.wrapperColSpan !== 'undefined' ? {span: query.queryFormatJson.wrapperColSpan} : wrapperCol">
                <view-select-tag
                  v-if="query.showType === 'page'"
                  :placeholder="$locale(query.queryFormatJson.placeholder || query.queryAlias || query.colName)"
                  v-model="query.queryDefaultValue"
                  :viewCode="query.queryFormatJson.viewCode"
                  :keyField="query.queryFormatJson.keyField"
                  :labelField="query.queryFormatJson.labelField"
                  :multi="query.queryFormatJson.multiple"
                />
                <query-field v-else :placeholder="$locale(query.queryFormatJson.placeholder || query.queryAlias || query.colName)" v-model.trim="query.queryDefaultValue"
                             :type="query.showType"
                             :linkageMap="linkageMap"
                             @setLinkageMap="changeQueryField(query, $event)"
                             :showConfig="query.queryFormatJson"
                             :dictOptions="dictOptions" :dictOptionsFlg="dictOptionsFlg"></query-field>
              </a-form-item>
            </a-col>
            <template v-if="toggleSearchStatus">
              <a-col v-for="(query, index) in queryColumns" :key="query.colCode"
                     :span="query.queryFormatJson.compColSpan || 6"
                     v-if="query.queryIsHidden === 'Y'">
                <a-form-item :label="$locale(query.queryAlias || query.colName)" :labelCol="typeof query.queryFormatJson.labelColSpan !== 'undefined' ? {span: query.queryFormatJson.labelColSpan} : labelCol" :wrapperCol="typeof query.queryFormatJson.wrapperColSpan !== 'undefined' ? {span: query.queryFormatJson.wrapperColSpan} : wrapperCol">
                  <view-select-tag
                    v-if="query.showType === 'page'"
                    :placeholder="$locale(query.queryFormatJson.placeholder || query.queryAlias || query.colName)"
                    v-model="query.queryDefaultValue"
                    :viewCode="query.queryFormatJson.viewCode"
                    :keyField="query.queryFormatJson.keyField"
                    :labelField="query.queryFormatJson.labelField"
                    :multi="query.queryFormatJson.multiple"
                  />
                  <query-field v-else :placeholder="$locale(query.queryFormatJson.placeholder || query.queryAlias || query.colName)" v-model.trim="query.queryDefaultValue"
                               :type="query.showType"
                               :linkageMap="linkageMap"
                               @setLinkageMap="changeQueryField(query, $event)"
                               :showConfig="query.queryFormatJson"
                               :dictOptions="dictOptions" :dictOptionsFlg="dictOptionsFlg"></query-field>
                </a-form-item>
              </a-col>
            </template>
            <a-col :span="6">
              <span style="margin-top: 4px;" class="table-page-search-submitButtons">
                <a-button type="primary" @click="searchQuery" icon="search">{{ $t('m.common.button.query') }}</a-button>
                <a-button type="default" @click="searchReset" icon="reload" style="margin-left: 8px">{{ $t('m.common.button.reset') }}</a-button>
                <CustomQuerySelect :view-code="viewCode"
                                      :query-columns="queryColumns"
                                      :dict-options="dictOptions"
                                      :dict-options-flg="dictOptionsFlg"
                                      @selectCustomQuery="selectCustomQuery"></CustomQuerySelect>
                <a @click="handleToggleSearch" style="margin-left: 8px" v-if="needToggleSearchStatus">
                  {{ toggleSearchStatus ? this.$t('m.common.button.fold') : this.$t('m.common.button.expand') }}
                  <ych-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
                </a>
              </span>
            </a-col>
          </a-row>
        </a-form>
      </div>
      <!-- 查询区域-END -->

      <!-- 操作按钮区域 -->
      <div class="table-operator" v-if="buttonsToolbar.length > 0">
          <a-button v-for="(button, index) in buttonsToolbar" :key="index"
                    v-if="(button.openType !== 'handleBatchDel' || !isFlow || canDel) && (button.openType !== 'handleBatchCollection' || isFlow) && isShowCondition(button)"
                    :type="button.buttonStyle" :icon="button.buttonIcon" @click="callFn(button)"
                    v-has="button.isPermission === 'Y' && button.permission ? viewCode + ':' + button.permission : null">
            {{$locale(button.buttonName)}}
          </a-button>
      </div>

      <div style="position: relative; top: -20px; float: right; height: 0;">
        <YchTableColSettings
          style="height: 16px; width: 16px;"
          :tableKey="viewCode"
          :initSettingColumns = "originalColumns"
          @customColumnChange="customColumnChange"
        >
        </YchTableColSettings>
      </div>

      <!-- table区域-begin -->
      <div>
        <a-table
          ref="table"
          size="middle"
          bordered
          rowKey="id"
          :columns="columns"
          :dataSource="dataSource"
          :pagination="pagination"
          :rowSelection="rowSelection"
          :scroll="scroll"
          @change="handleTableChange"
          :customRow="clickThenCheck"
        >
          <template slot="serialNum" slot-scope="text,record,index">
            {{pagination?((pagination.current-1) * pagination.pageSize + parseInt(index) + 1):parseInt(index)+1}}
          </template>

          <template slot="action" slot-scope="text, record">
              {{void(a=0)}}
            <template v-for="(button, index) in expandBut">

              <span v-if="isShowCondition(button, record)" v-has="button.isPermission === 'Y' && button.permission ? viewCode + ':' + button.permission : null">
                  {{void(a=a+1)}}
                <a-divider v-if="a>1" type="vertical" />
                <a @click="callFn(button, record)"

                >{{$locale(button.buttonName)}}</a>

              </span>

            </template>
            <a-divider v-if="showMoreBut(record) && a>0" type="vertical"/>
            <a-dropdown v-if="showMoreBut(record)">
              <a class="ant-dropdown-link">{{$t('m.common.button.more')}}
                <ych-icon type="down"/>
              </a>
              <a-menu slot="overlay">
                <a-menu-item v-for="(button, index) in moreBut" :key="index"
                             v-if="isShowCondition(button, record)"
                             v-has="button.isPermission === 'Y' && button.permission ? viewCode + ':' + button.permission : null"
                >
                  <a @click="callFn(button, record)">{{$locale(button.buttonName)}}</a>
                </a-menu-item>
              </a-menu>
            </a-dropdown>
          </template>

          <template slot="image" slot-scope="text, record">
            <ViewImageSlot v-model="text"/>
          </template>

          <template slot="file" slot-scope="text, record">
            <ViewFileSlot v-model="text"/>
          </template>

          <template slot="links" slot-scope="text, record">
            <a :href="text" target="_blank" :title="text">{{text}}</a>
          </template>

          <template slot="switch" slot-scope="text, record">
            <a-switch :disabled="true" :checked="text === 'true'"/>
          </template>

          <template slot="actionConfig" slot-scope="text, record, index, col">
            <a @click="callFn(null, record, col)" :title="text">{{text}}</a>
          </template>

          <template slot="html" slot-scope="text, record">
            <div v-html="text"></div>
          </template>
        </a-table>
      </div>

      <!-- 尾部插槽 -->
      <component
        ref="footer"
        v-if="footer.show"
        :is="footer.componentFile"
        :stores="stores"
      />
    </a-spin>

    <redirect-modal ref="flowForm" @refreshParent="modalFormOk" :ignoreSec="flowScope === 'all' || flowScope==='noLimit'"
                    :stores="stores"></redirect-modal>

    <form-redirect-modal ref="form" @refreshParent="modalFormOk" :stores="stores"></form-redirect-modal>

    <form-redirect-div ref="formInCurrent" :stores="stores"></form-redirect-div>

    <component :is="componentFile" @refreshParent="modalFormOk" :obj="componentObj"
               :stores="stores"/>

    <import-dialog ref="importDialog" :viewCode="viewCode" :viewName="tableShow.viewName" @loadData="loadData"
                   :stores="stores"></import-dialog>

    <!--查看子表-->
    <ych-modal
      :fullscreen="subView.dialogSize === 'full'"
      :size="subView.dialogSize === 'default' ? 'large' : subView.dialogSize"
      :title="subView.title"
      :visible="subView.visible"
      @cancel="handleCancelSubView"
      :cancelText="$t('m.common.button.close')">

      <view-layout-redirect v-if="subView.visible" :viewCode="subView.viewCode" :stores="stores"
                            :parameterValue="subView.parameterValue" @openSubView="openSubViewInSubView"
                            @handleCancelSubView="handleCancelSubView">
      </view-layout-redirect>

      <template slot="footer">
        <a-button key="back" @click="handleCancelSubView">{{ $t('m.common.button.close') }}</a-button>
      </template>
    </ych-modal>
    <bpm-collection-dialog ref="bpmCollectionDialog"></bpm-collection-dialog>
  </div>
</template>

<script>

  import { getAction, deleteAction, putAction, postAction, httpAction, downFile } from '@/api/manage'
  import RedirectModal from '../../bpm/redirect/RedirectModal'
  import FormRedirectModal from './FormRedirectModal'
  import FormRedirectDiv from './FormRedirectDiv'
  import QueryField from '../select/tag/QueryField'
  import { initDictOptionMap } from '@/components/dict/YchDictSelectUtil'
  import ViewSelectTag from '../select/viewSelect/ViewSelectTag'
  import error from '../../common/exception/404'
  import ViewImageSlot from './ViewImageSlot'
  import ViewFileSlot from './ViewFileSlot'
  import YchConstant from "@/api/YchConstant";
  import {handleCreateFunc, handleExecFunc} from '@/utils/actions'
  import ImportDialog from './ImportDialog'
  import { elValue } from '../ElValue'
  import moment from 'moment'
  import RelationUtil from "./RelationUtil";
  import RefreshUtil from "./RefreshUtil";
  import YchTableColSettings from '@/components/ych/YchTableColSettings'
  import {TabInCurrentMixin} from './TabInCurrentMixin'
  import CustomQuerySelect from '../customQuery/CustomQuerySelect'
  import BpmCollectionDialog from '../../bpm/modules/BpmCollectionDialog'

  export default {
    name: 'ViewRedirect',
    mixins:[TabInCurrentMixin],
    components: {
      RedirectModal,
      FormRedirectModal,
      FormRedirectDiv,
      QueryField,
      ViewSelectTag,
      error,
      ViewImageSlot,
      ViewFileSlot,
      ImportDialog,
      ViewLayoutRedirect: () => import('./ViewLayoutRedirect'),
      YchTableColSettings,
      CustomQuerySelect,
      BpmCollectionDialog
    },
    props: {
      viewCode: String,
      relationList: Array,
      refreshMap: Object,
      subViews: Object,
      relationStatus: String,
      relationOpenFks: String,
      isShowInTab: Boolean,
      parameterValue: {
        type: Array,
        default: () => []
      },
      stores: {
        type: Object,
        default: () => {
          return {}
        }
      },
      tabConfig: Object
    },
    data () {
      return {
        componentFile: null,
        componentUrl: null,
        componentObj: {},
        header: {show: false},
        footer: {show: false},
        tableName: null,
        buttonsToolbar: [],
        buttonsInline: [],
        queryColumns: [],
        tableCols: [],
        columns: [],
        originalColumns: [],
        isFlow: false,
        flowScope: null,
        canDel: false,
        myInstanceClassify: 'all',
        dictOptions: {},
        linkageMap: {},
        dictOptionsFlg: 0,
        columnLineNum: {
          title:this.$t('m.common.label.number'),
          dataIndex: 'rowIndex',
          key: 'rowIndex',
          width: "50px",
          align: 'center',
          scopedSlots: { customRender: 'serialNum' },
        },
        columnBpmStatus: {
          title: this.$t('m.bpm.common.bpmStatus'),
          align: 'center',
          width: "120px",
          dataIndex: 'bpmStatus'
        },
        columnBpmActivity: {
          title: this.$t('m.bpm.common.bpmActivity'),
          align: 'center',
          width: "100px",
          dataIndex: 'bpmActivity',
          ellipsis: true,
        },
        columnAction: {
          title: this.$t('m.common.label.operate'),
          dataIndex: 'action',
          align: 'center',
          width: "120px",
          scopedSlots: { customRender: 'action' },
        },
        rowSelection: {
          selectedRowKeys: [],
          selectionRows: [],
          onChange: (selectedRowKeys, selectionRows) => {
            this.rowSelection.selectedRowKeys = selectedRowKeys
            const aa = this.rowSelection.selectionRows.filter(item => selectedRowKeys.indexOf(item.id) !== -1)
            const bb = aa.map(row => row['id'])
            const cc = selectionRows.filter(item => bb.indexOf(item.id) === -1)
            this.rowSelection.selectionRows = [...aa, ...cc]
          }
        },
        dataSource: [],
        scroll: {},
        pagination: {
          current: 1,
          pageSize: 10,
          pageSizeOptions: ['10', '20', '50', '100', '200', '500'],
          showTotal: (total, range) => {
            return this.$t('m.common.label.page_total', [range[0], range[1], total])
          },
          showQuickJumper: true,
          showSizeChanger: true,
          total: 0
        },
        sorter:{},
        spinning: 0,
        toggleSearchStatus: false,
        needToggleSearchStatus: false,
        url: {
          getViewModel: YchConstant.PREFIX_EFORM + '/engine/viewEngine/getViewModel',
          queryViewListPage: YchConstant.PREFIX_EFORM + '/engine/viewEngine/queryViewListPage',
          queryViewList: YchConstant.PREFIX_EFORM + '/engine/viewEngine/queryViewList',
          removeData: YchConstant.PREFIX_EFORM + '/engine/viewEngine/removeDataByBoCode',
          exportXlsUrl: YchConstant.PREFIX_EFORM + '/engine/viewEngine/exportXls',
          getExcelMax: YchConstant.PREFIX_EFORM + '/engine/viewEngine/getExcelMax',
        },
        fks: [],
        refreshObj: {},
        isParentTable: undefined,
        parentValue: {},
        clickRecord: {},
        tableShow: {},
        relationValue: null,
        customRowFunc: null,
        subView: {
          title: null,
          visible: false,
          viewCode: null,
          dialogSize: 'default',
          parameterValue: [],
        },
        labelCol: {
          span: 8
        },
        wrapperCol: {
          span: 16
        },
      }
    },
    computed: {
      expandBut() {
        const buts = this.buttonsInlineFilter.filter(button => button.isExpand === 'Y')
        if (buts.length === 0 && this.buttonsInlineFilter.length > 0) {
          return [this.buttonsInlineFilter[0]]
        }
        return buts;
      },
      moreBut() {
        const buts = this.buttonsInlineFilter.filter(button => button.isExpand === 'N')
        if (buts.length > 0 && buts.length === this.buttonsInlineFilter.length) {
          buts.shift();
        }
        return buts;
      },
      buttonsInlineFilter() {
        return this.buttonsInline.filter(button => (button.openType !== 'handleDel' || !this.isFlow || this.canDel))
      },
    },
    watch: {
      refreshMap: {
        handler() {
          const _val = this.refreshObj
          this.refreshObj = RefreshUtil.getRefreshValue(this.refreshMap, {
            tableName: this.tableName,
            refreshObj: this.refreshObj,
          })
          if (_val !== this.refreshObj && this.refreshObj.type === 'form') {
            this.loadData()
          }
        }
      },
      relationList: {
        handler() {
          const _fks = this.fks
          this.initRelation()
          if (_fks !== this.fks) {
            this.loadData(1)
          }
        }
      },
    },
    created () {
      if (this.subViews && this.subViews[this.viewCode]) {
        this.init(this.subViews[this.viewCode])
        // this.changePkFlg()
      } else {
        this.spinning++
        getAction(this.url.getViewModel, { viewCode: this.viewCode }).then((res) => {
          if (res.success) {
            this.init(res.result)
            // this.changePkFlg()
          } else {
            this.messageUtil.warning(res.message)
          }
        }).finally(() => {
          this.spinning--
        })
      }

      // 把当前对象放入stores，方便其他对象使用
      if (!this.stores.$vm) {
        this.stores.$vm = {}
      }
      this.stores.$vm[this.viewCode] = this
    },
    inject: ['addRouter'],
    methods: {
      selectCustomQuery(queryConditonStr){
        let queryConditon = JSON.parse(queryConditonStr)
        if(queryConditon && queryConditon.length>0 && this.queryColumns && this.queryColumns.length>0){
          for(let i=0;i<this.queryColumns.length;i++){
            for(let j=0;j<queryConditon.length;j++){
              if(this.queryColumns[i].colCode == queryConditon[j].colCode){
                this.queryColumns[i].queryDefaultValue = queryConditon[j].queryDefaultValue
              }
            }
          }
          this.loadData(1)
        }
      },
      customColumnChange(settingColumns){
        this.columns = settingColumns.filter(item=>item.visible === true)
      },
      initRelation() {
        this.fks = RelationUtil.getChangedRelation({
          relationList: this.relationList,
          tableName: this.tableName,
          fks: this.fks,
          parentValue: this.parentValue,
          itemCode: this.viewCode,
          relationOpenFks: this.relationOpenFks,
        })
        this.isParentTable = RelationUtil.isParentTable({
          relationList: this.relationList,
          tableName: this.tableName,
          value: this.isParentTable,
          relationStatus: this.relationStatus,
        })
      },
      isShowCondition(button, record) {
        if (!button.showCondition) {
          return true
        }
        const func = handleCreateFunc(button.showCondition, this)
        return handleExecFunc(func, { record })
      },
      showMoreBut(record) {
        const show = this.moreBut.length > 0;
        if (!show) {
          return false
        }
        for (let i = 0; i < this.moreBut.length; i++) {
          const button = this.moreBut[i]
          if (this.isShowCondition(button, record)) {
            return true
          }
        }
      },
      init (result) {
        const that = this
        this.tableShow = result.tableShow
        this.tableName = result.tableShow.tableName
        //查询条件
        this.queryColumns = result.queryShow || []

        // 自定义行
        if(this.tableShow && this.tableShow.customRowFunc){
          this.customRowFunc = handleCreateFunc(this.tableShow.customRowFunc, this)
        }

        let elValueValue = result.elValue
        this.queryColumns.forEach(query => {
          query.queryFormatJson = query.queryFormat ? JSON.parse(query.queryFormat) : {}

          if (query.queryFormatJson.dictOption && query.queryFormatJson.dictOption.dictCode) {
            that.dictOptions[query.queryFormatJson.dictOption.dictCode] = []
          }

          if(elValueValue && query.queryDefaultValue){
            query.queryDefaultValue = elValue(elValueValue, query.queryDefaultValue)
            if (query.showType === 'date') {
              if(query.queryDefaultValue){
                let mountDate = moment(query.queryDefaultValue, 'YYYY-MM-DD HH:mm:ss')
                let queryFormat = 'YYYY-MM-DD'
                if(query.queryFormatJson && query.queryFormatJson.format){
                  queryFormat = query.queryFormatJson.format
                }
                let mountStr = mountDate.format(queryFormat)
                mountStr = moment(mountStr, queryFormat).format('YYYY-MM-DD HH:mm:ss')
                query.queryDefaultValue = mountStr
              }
            }
          }
        })
        this.needToggleSearchStatus = this.queryColumns.filter(vo => vo.queryIsHidden === 'Y').length > 0
        //按钮
        this.buttonsToolbar = result.buttonShow.filter(vo => vo.buttonType === 'toolbar')
        this.buttonsInline = result.buttonShow.filter(vo => vo.buttonType === 'inline')

        //复选框
        if (result.tableShow.checkType === 'N') {
          this.rowSelection = null
        }
        //行号
        if (result.tableShow.isLineNum === 'Y') {
          this.columns.push(this.columnLineNum)
        }
        // 临时变量，判断有无居左固定列
        let left_flg = false;
        //字段
        this.tableCols = result.tableShow.columnShow || []
        result.tableShow.columnShow.forEach(vo => {
          const column = {
            title: this.$locale(vo.colAlias || vo.colName),
            dataIndex: vo.colCode,
            mergeHeaderName: vo.mergeHeaderName,
          }
          if (vo.alignType) {
            column.align = vo.alignType
          }
          //宽度
          if (vo.colWidth) {
            column.width = vo.colWidth + "px"
          }
          // 固定列
          if(vo.fixed && vo.fixed !== 'none' && result.tableShow.scrollEnable === 'Y'){
            column.fixed = vo.fixed
            if(vo.fixed === 'left'){
              left_flg = true;
            }
          }
          // 超宽自动省略
          if(vo.isEllipsis === 'Y'){
            column.ellipsis = true;
          }
          //是否可排序
          if(vo.isSort === 'Y'){
            column.sorter = true;
          }
          // 数据转换配置
          if (vo.dataConfig) {
            const dataConfig = JSON.parse(vo.dataConfig)
            if (dataConfig.type === 'image') {
              // 转换成图片
              column.scopedSlots = { customRender: 'image' }
            } else if (dataConfig.type === 'file') {
              // 转换成附件
              column.scopedSlots = { customRender: 'file' }
            } else if (dataConfig.type === 'links') {
              // 转换成超链接
              column.scopedSlots = { customRender: 'links' }
            } else if (dataConfig.type === 'switch') {
              // 转换成开关
              column.scopedSlots = { customRender: 'switch' }
            } else if (dataConfig.type === 'html') {
              // 转换成html
              column.scopedSlots = { customRender: 'html' }
            } else if(dataConfig.type === 'ellipsis'){
              // 转换成不换行，兼容历史
              column.ellipsis = true;
            }
          }

          // 动作，前置数据转换优先
          if (!column.scopedSlots && vo.actionConfig) {
            column.scopedSlots = {customRender: 'actionConfig'}
          }
          this.columns.push(column)
        })

        // 行号居左
        if(left_flg){
          this.columnLineNum.fixed = 'left'
        }

        this.initDictConfig()

        //流程
        if (result.tableShow.isFlow === 'Y') {
          this.isFlow = true
          this.flowScope = result.tableShow.flowScope
          if(this.flowScope==='myTask'){
            this.myInstanceClassify = 'todo'
          }else{
            this.myInstanceClassify = 'all'
          }
          if (result.tableShow.disableBpmStatus !== 'Y') {
            this.columns.push(this.columnBpmStatus)
          }
          if (result.tableShow.disableBpmActivity !== 'Y') {
            this.columns.push(this.columnBpmActivity)
          }
        }
        //是否需要操作列
        if (this.buttonsInline.length > 0) {
          this.columns.push(this.columnAction)
          if (result.tableShow.actionWidth) {
            this.columnAction.width = result.tableShow.actionWidth + 'px'
          }
        }

        // 固定操作列
        if (result.tableShow.fixedAction === 'Y' && result.tableShow.scrollEnable === 'Y') {
          this.columnAction.fixed = 'right'
        }

        // 固定流程列
        if (result.tableShow.fixedBpmColumn === 'Y' && result.tableShow.scrollEnable === 'Y') {
          this.columnBpmStatus.fixed = 'right'
          this.columnBpmActivity.fixed = 'right'
          // 自动省略与固定列不能同时使用
          delete this.columnBpmActivity['ellipsis']
        }

        //是否分页
        if (result.tableShow.isPage === 'N') {
          this.pagination = false
        } else {
          //初始分页大小
          if (result.tableShow.pageNum && result.tableShow.pageNum > 0) {
            this.pagination.pageSize = result.tableShow.pageNum
          }
        }

        //是否横向滚动
        if (result.tableShow.scrollEnable === 'Y') {
          const scrollWidth = result.tableShow.scrollWidth || 1300
          this.scroll = {
            x: scrollWidth
          }
        } else {
          this.scroll = {}
        }

        // 合并表头
        this.mergeHeader();

        //深拷贝
        let dealColumns = [];
        this.columns.map(item => {
          let newObj = Object.assign({}, item);
          newObj['visible'] = item.visible !== false
          dealColumns.push(newObj);
        });
        //原始列信息
        this.originalColumns = dealColumns

        this.initRelation()

        // 插槽
        const customSlot = result.tableShow.customSlot ? JSON.parse(result.tableShow.customSlot) : {}
        if (customSlot.header) {
          this.header.componentFile = (resolve) => ({
            component: import(`@/views/` + customSlot.header + '.vue'),
            error: error,
            delay: 200,
            timeout: 10000
          })
          this.header.show = true
        }
        if (customSlot.footer) {
          this.footer.componentFile = (resolve) => ({
            component: import(`@/views/` + customSlot.footer + '.vue'),
            error: error,
            delay: 200,
            timeout: 10000
          })
          this.footer.show = true
        }

        //默认查询
        if (result.tableShow.isQuery === 'Y' && this.checkFks()) {
          this.loadData()
        }
      },
      mergeHeader(){
        //合并表头处理
        let mergeHeaderNameMap = new Map
        let columnIndex = 0
        let mergeCount = 0
        this.columns.forEach(item => {
            if (item.mergeHeaderName) {
              if (!mergeHeaderNameMap.has(item.mergeHeaderName)) {
                let mergeObj = {
                  index: columnIndex + mergeCount,
                  title: this.$locale(item.mergeHeaderName),
                  children: []
                }
                mergeObj.children.push(item)
                mergeHeaderNameMap.set(item.mergeHeaderName, mergeObj)
                mergeCount++
              } else {
                mergeHeaderNameMap.get(item.mergeHeaderName).children.push(item)
              }
            }
            columnIndex++
          }
        )
        if (mergeHeaderNameMap.size > 0) {
          let newColumns = this.columns
          mergeHeaderNameMap.forEach(item => {
            newColumns.splice(item.index, 0, item)
          })
          this.columns = newColumns.filter(item => !(item.mergeHeaderName && item.mergeHeaderName.length > 0))
        }
      },
      loadData (arg) {
        let url
        if (this.pagination) {
          //加载数据 若传入参数1则加载第一页的内容
          if (arg === 1) {
            this.pagination.current = 1
          }
          url = this.url.queryViewListPage + '?viewCode=' + this.viewCode + '&pageNo=' + this.pagination.current + '&pageSize=' + this.pagination.pageSize
        } else {
          url = this.url.queryViewList + '?viewCode=' + this.viewCode
        }
        //排序字段
        if(this.sorter && this.sorter.field){
          url +="&sorterField="+this.sorter.field
        }
        //升序or降序
        if(this.sorter && this.sorter.order){
          let order = this.sorter.order.substr(0,this.sorter.order.indexOf("end"))
          url +="&sorterOrder="+order
        }
        this.spinning++
        const queryValue = this.getQuery();
        //加载前事件
        if (this.tableShow.beforeScript) {
          const _that = this
          const func = handleCreateFunc(this.tableShow.beforeScript, this)
          const func_result = handleExecFunc(func, {url, arg, queryValue}, function(){
            _that.loadDataCallback(url, queryValue, arg);
          })
          if(!func_result) return;
        }
        this.loadDataCallback(url, queryValue, arg);
      },
      loadDataCallback(url, queryValue, arg){
        postAction(url, queryValue).then((res) => {
          if (res.success) {
            if (this.pagination) {
              this.dataSource = res.result.records
              this.pagination.total = res.result.total
              this.pagination.current = res.result.current
            } else {
              this.dataSource = res.result
            }

            this.refreshPk()

            //
            this.canDel = this.myInstanceClassify === 'noRun' || this.myInstanceClassify === 'start'

            //加载后事件
            if (this.tableShow.afterScript) {
              const func = handleCreateFunc(this.tableShow.afterScript, this)
              handleExecFunc(func, {arg, queryValue, res})
            }
          } else {
            this.messageUtil.warning(res.message)
          }
        }).finally(() => {
          this.spinning--
        })
      },
      getQuery() {
        const queryValue = []
        this.queryColumns.forEach(query => {
          //时间范围查询
          if (query.queryDefaultValue && query.queryDefaultValue.startsWith('[') && query.queryDefaultValue.endsWith(']')) {
            const queryDefaultValueJson = JSON.parse(query.queryDefaultValue)
            if (queryDefaultValueJson.length === 2) {
              const item_start = {
                colCode: query.colCode,
                queryValue: queryDefaultValueJson[0]
              }
              const item_end = {
                colCode: query.colCode + '-end',
                queryValue: queryDefaultValueJson[1]
              }
              queryValue.push(item_start)
              queryValue.push(item_end)
            }
          } else if (query.queryDefaultValue) {
            const item = {
              colCode: query.colCode,
              queryValue: query.queryDefaultValue
            }
            queryValue.push(item)
          }
        })
        return {
          queryValue: queryValue,
          myInstanceClassify: this.myInstanceClassify,
          fks: this.fks,
          parameterValue: this.parameterValue
        }
      },
      //查询
      searchQuery () {
        this.loadData(1)
      },
      //重置
      searchReset () {
        this.queryColumns.forEach(vo => vo.queryDefaultValue = undefined)
        this.myInstanceClassify = 'all'
        this.linkageMap = {}
        this.loadData(1)
      },
      //展开
      handleToggleSearch () {
        this.toggleSearchStatus = !this.toggleSearchStatus
      },
      //分页、排序、筛选变化时触发
      handleTableChange (pagination, filters, sorter) {
        this.pagination = this.pagination ? pagination : false
        this.sorter = sorter
        this.loadData()
      },
      //清空
      onClearSelected () {
        this.rowSelection.selectedRowKeys = []
        this.rowSelection.selectionRows = []
      },
      initDictConfig () {
        let dictCodes = Object.keys(this.dictOptions).join(',')
        if (dictCodes && dictCodes.length > 0) {
          initDictOptionMap(dictCodes).then((res) => {
            if (res.success) {
              Object.keys(this.dictOptions).forEach(key => {
                this.$set(this.dictOptions, key, res.result[key])
              })
              //触发查询框重新加载
              this.dictOptionsFlg = this.dictOptionsFlg + 1
            }
          })
        }
      },
      changeQueryField(query, value) {
        if (query.showType && query.colCode) {
          this.linkageMap = {...this.linkageMap}
          this.linkageMap[query.colCode] = value;
        }
      },
      clickThenCheck(record) {
        let result = {};
        if (this.customRowFunc) {
          const func_result = handleExecFunc(this.customRowFunc, {record})
          result = func_result || {}
        }
        result["on"] = {
          click: () => {
            if (!this.isParentTable || this.clickRecord.id === record.id) {
              return
            }
            this.setPk(record)
          }
        }
        return result
      },
      refreshPk () {
        if (!this.isParentTable) {
          return
        }
        if (this.dataSource.length === 0 && !this.clickRecord.id) {
          return
        }
        let current
        if (this.clickRecord.id) {
          current = this.dataSource.find(vo => vo.id === this.clickRecord.id)
        }
        if (!current) {
          this.setPk(this.dataSource.length > 0 ? this.dataSource[0] : {})
        } else {
          this.setPk(current)
        }
      },
      setPk (record) {
        this.clickRecord = record
        this.$emit('setPk', {
          record: record,
          tableName: this.tableName,
          relationStatus: this.relationStatus,
        })
        if (this.rowSelection) {
          if (record.id) {
            this.rowSelection.selectedRowKeys = [record.id]
            this.rowSelection.selectionRows = [record]
          } else {
            this.rowSelection.selectedRowKeys = []
            this.rowSelection.selectionRows = []
          }
        }
      },
      checkFks () {
        return RelationUtil.checkFks({
          fks: this.fks,
        })
      },
      unionParentData() {
        let data = {};
        this.parameterValue.forEach(item => {
          data[item.colCode] = item.queryValue
        })
        data = Object.assign(data, this.parentValue)
        return data
      },
      callFn (button, record, col) {
        if (!button && col) {
          const column = this.tableCols.find(vo => vo.colCode === col.dataIndex)
          button = JSON.parse(column.actionConfig)
        }
        this[button.openType].apply(this, [button, record])
      },
      handleAddFlow (button, record) {
        const formCode = button.formCode
        const viewCode = button.viewCode
        if (!formCode && !viewCode) {
          this.messageUtil.warning(this.$t('m.eform.formDesign.label.no_form_no_view'))
          return
        }
        if (!this.checkFks()) {
          this.messageUtil.warning(button.customCheckFksMessage || this.$t('m.eform.formDesign.label.checkFks_error'))
          return
        }
        if (button.beforeScript) {
          const _that = this
          const func = handleCreateFunc(button.beforeScript, this)
          const func_result = handleExecFunc(func, {button,formCode, record, viewCode}, function(){
            _that.handleAddFlowCallback(button, formCode, record, viewCode)
          })
          if(!func_result) return;
        }
        this.handleAddFlowCallback(button, formCode, record, viewCode)
      },
      handleAddFlowCallback(button, formCode, record, viewCode){
        const code = formCode || viewCode
        let router = null
        if (button.dialogSize === 'tab') {
          if (!this.isShowInTab) {
            button.dialogSize = null
            // this.messageUtil.warning("弹框模式下不支持使用新页签打开方式")
          } else {
            router = this.addRouter({
              path: '/bpm/addFromBusiness/' + code,
              component: resolve => require(['@/views/bpm/redirect/RedirectTab.vue'], resolve),
              props: {
                formCode: code,
                func: 'addFromBusiness',
                fks: JSON.parse(JSON.stringify(this.fks)),
                parentValue: this.unionParentData(),
                id: code,
              },
              meta: {
                title: this.$t('m.common.button.addFlow'),
              }
            }, true);
          }
          if (router) {
            this.$router.push(router).catch(err => {})
          }
        }
        if (!router) {
          this.$refs.flowForm.addFromBusiness(code, JSON.parse(JSON.stringify(this.fks)), this.unionParentData(), button.dialogSize)
        }
        if (button.afterScript) {
          const func = handleCreateFunc(button.afterScript, this)
          handleExecFunc(func, {button, record})
        }
      },
      handleAdd(button, record) {
        const formCode = button.formCode
        const viewCode = button.viewCode
        if (!formCode && !viewCode) {
          this.messageUtil.warning(this.$t('m.eform.formDesign.label.no_form_no_view'))
          return
        }
        if (!this.checkFks()) {
          this.messageUtil.warning(button.customCheckFksMessage || this.$t('m.eform.formDesign.label.checkFks_error'))
          return
        }
        if (button.beforeScript) {
          const _that = this
          const func = handleCreateFunc(button.beforeScript, this)
          const func_result = handleExecFunc(func, {button, formCode, viewCode, record}, function () {
            _that.handleAddCallback(button, formCode, viewCode, record)
          })
          if (!func_result) return;
        }
        this.handleAddCallback(button, formCode, viewCode, record)
      },
      handleAddCallback(button, formCode, viewCode, record) {
        let formType = formCode ? 'form' : 'view'
        let code = formCode || viewCode

        let router = null
        if (button.dialogSize === 'tab') {
          if (!this.isShowInTab) {
            button.dialogSize = null
            // this.messageUtil.warning("弹框模式下不支持使用新页签打开方式")
          } else {
            router = this.addRouter({
              path: '/eform/add/' + code,
              component: resolve => require(['@/views/eform/redirect/FormRedirectTab.vue'], resolve),
              props: {
                formCode: code,
                func: 'add',
                fks: JSON.parse(JSON.stringify(this.fks)),
                parentValue: this.unionParentData(),
                formType: formType,
              },
              meta: {
                title: this.$t('m.eform.formDesign.label.xin-zeng-biao-dan'),
              }
            }, true);
          }
          if (router) {
            this.$router.push(router).catch(err => {})
          }
        }
        if (!router) {
          if (button.dialogSize === 'tabInCurrent' && !this.isShowInTab) {
            button.dialogSize = null
            // this.messageUtil.warning("弹框模式下不支持使用本页签覆盖方式")
          }
          if (button.dialogSize === 'tabInCurrent') {
            this.addFormInCurrentTab({
              formCode: code,
              fks: JSON.parse(JSON.stringify(this.fks)),
              parentValue: this.unionParentData(),
              dialogSize: button.dialogSize,
              formType: formType,
            }, this.modalFormOk)
          } else {
            this.$refs.form.addForm({
              formCode: code,
              fks: JSON.parse(JSON.stringify(this.fks)),
              parentValue: this.unionParentData(),
              dialogSize: button.dialogSize,
              formType: formType,
            })
          }
        }
        if (button.afterScript) {
          const func = handleCreateFunc(button.afterScript, this)
          handleExecFunc(func, {button, record})
        }
      },
      handleEdit(button, record) {
        const formCode = button.formCode
        const viewCode = button.viewCode
        if (!formCode && !viewCode) {
          this.messageUtil.warning(this.$t('m.eform.formDesign.label.no_form_no_view'))
          return
        }
        if (!record) {
          if (!this.rowSelection || this.rowSelection.selectedRowKeys.length !== 1) {
            this.messageUtil.warning(this.$t('m.common.tip.select_one_warn'))
            return
          }
          record = this.rowSelection.selectionRows[0]
        }
        let id = record.id;
        if (button.beforeScript) {
          const _that = this
          const func = handleCreateFunc(button.beforeScript, this)
          const func_result = handleExecFunc(func, {button, id, formCode, viewCode, record}, function () {
            _that.handleEditCallback(button, id, formCode, viewCode, record)
          })
          if (!func_result) return;
        }
        this.handleEditCallback(button, id, formCode, viewCode, record)
      },
      handleEditCallback(button, id, formCode, viewCode, record) {
        let formType = formCode ? 'form' : 'view'
        let code = formCode || viewCode

        let router = null
        if (button.dialogSize === 'tab') {
          if (!this.isShowInTab) {
            button.dialogSize = null
            // this.messageUtil.warning("弹框模式下不支持使用新页签打开方式")
          } else {
            router = this.addRouter({
              path: '/eform/edit/' + code + "/" + id,
              component: resolve => require(['@/views/eform/redirect/FormRedirectTab.vue'], resolve),
              props: {
                formCode: code,
                func: 'edit',
                formId: id,
                formType: formType,
              },
              meta: {
                title: this.$t('m.eform.formDesign.label.bian-ji-biao-dan'),
              }
            });
          }
          if (router) {
            this.$router.push(router).catch(err => {})
          }
        }
        if (!router) {
          if (button.dialogSize === 'tabInCurrent' && !this.isShowInTab) {
            button.dialogSize = null
            // this.messageUtil.warning("弹框模式下不支持使用本页签覆盖方式")
          }
          if (button.dialogSize === 'tabInCurrent') {
            this.editFormInCurrentTab({
              id: id,
              formCode: code,
              dialogSize: button.dialogSize,
              formType: formType,
            }, this.modalFormOk)
          } else {
            this.$refs.form.editForm({
              id: id,
              formCode: code,
              dialogSize: button.dialogSize,
              formType: formType,
            })
          }
        }
        if (button.afterScript) {
          const func = handleCreateFunc(button.afterScript, this)
          handleExecFunc(func, {button, record})
        }
      },
      handleDetailFlow (button, record) {
        const formCode = button.formCode
        const viewCode = button.viewCode
        if (!formCode && !viewCode) {
          this.messageUtil.warning(this.$t('m.eform.formDesign.label.no_form_no_view'))
          return
        }
        if (!record) {
          if (!this.rowSelection || this.rowSelection.selectedRowKeys.length !== 1) {
            this.messageUtil.warning(this.$t('m.common.tip.select_one_warn'))
            return
          }
          record = this.rowSelection.selectionRows[0]
        }
        let id = record.id;
        if (button.beforeScript) {
          const _that = this
          const func = handleCreateFunc(button.beforeScript, this)
          const func_result = handleExecFunc(func, {button, id, formCode, record, viewCode}, function(){
            _that.handleDetailFlowCallback(button, id, formCode, record, viewCode)
          })
          if(!func_result) return;
        }
        this.handleDetailFlowCallback(button, id, formCode, record, viewCode)
      },
      handleDetailFlowCallback(button, id, formCode, record, viewCode){
        const code = formCode || viewCode
        let router = null
        if (button.dialogSize === 'tab') {
          if (!this.isShowInTab) {
            button.dialogSize = null
            // this.messageUtil.warning("弹框模式下不支持使用新页签打开方式")
          } else {
            router = this.addRouter({
              path: '/bpm/detailFromBusiness/' + code + '/' + id,
              component: resolve => require(['@/views/bpm/redirect/RedirectTab.vue'], resolve),
              props: {
                formCode: code,
                func: 'detailFromBusiness',
                id: id,
              },
              meta: {
                title: this.$t('m.bpm.common.bpmDetail'),
              }
            });
          }
          if (router) {
            this.$router.push(router).catch(err => {})
          }
        }
        if (!router) {
          this.$refs.flowForm.detailFromBusiness(id, code, button.dialogSize)
        }
        if (button.afterScript) {
          const func = handleCreateFunc(button.afterScript, this)
          handleExecFunc(func, {button, record})
        }
      },
      handleDetail(button, record) {
        const formCode = button.formCode
        const viewCode = button.viewCode
        if (!formCode && !viewCode) {
          this.messageUtil.warning(this.$t('m.eform.formDesign.label.no_form_no_view'))
          return
        }
        if (!record) {
          if (!this.rowSelection || this.rowSelection.selectedRowKeys.length !== 1) {
            this.messageUtil.warning(this.$t('m.common.tip.select_one_warn'))
            return
          }
          record = this.rowSelection.selectionRows[0]
        }
        let id = record.id;
        if (button.beforeScript) {
          const _that = this
          const func = handleCreateFunc(button.beforeScript, this)
          const func_result = handleExecFunc(func, {button, id, formCode, viewCode, record}, function () {
            _that.handleDetailCallback(button, id, formCode, viewCode, record)
          })
          if (!func_result) return;
        }
        this.handleDetailCallback(button, id, formCode, viewCode, record)
      },
      handleDetailCallback(button, id, formCode, viewCode, record) {
        let formType = formCode ? 'form' : 'view'
        let code = formCode || viewCode

        let router = null
        if (button.dialogSize === 'tab') {
          if (!this.isShowInTab) {
            button.dialogSize = null
            // this.messageUtil.warning("弹框模式下不支持使用新页签打开方式")
          } else {
            router = this.addRouter({
              path: '/eform/detail/' + code + "/" + id,
              component: resolve => require(['@/views/eform/redirect/FormRedirectTab.vue'], resolve),
              props: {
                formCode: code,
                func: 'detail',
                formId: id,
                formType: formType,
              },
              meta: {
                title: this.$t('m.eform.formDesign.label.cha-kan-biao-dan'),
              }
            });
          }
          if (router) {
            this.$router.push(router).catch(err => {})
          }
        }
        if (!router) {
          if (button.dialogSize === 'tabInCurrent' && !this.isShowInTab) {
            button.dialogSize = null
            // this.messageUtil.warning("弹框模式下不支持使用本页签覆盖方式")
          }
          if (button.dialogSize === 'tabInCurrent') {
            this.detailFormInCurrentTab({
              id: id,
              formCode: code,
              dialogSize: button.dialogSize,
              formType: formType,
            }, this.modalFormOk)
          } else {
            this.$refs.form.detailForm({
              id: id,
              formCode: code,
              dialogSize: button.dialogSize,
              formType: formType,
            })
          }
        }
        if (button.afterScript) {
          const func = handleCreateFunc(button.afterScript, this)
          handleExecFunc(func, {button, record})
        }
      },
      handleBatchDel (button) {
        this.handleDel(button)
      },
      handleDel (button, record) {
        const objectCode = button.objectCode
        if (!objectCode) {
          this.messageUtil.warning(this.$t('m.eform.formDesign.label.mei-you-pei-zhi-er-mo-xing'))
          return
        }
        let ids
        if (!record) {
          if (!this.rowSelection || this.rowSelection.selectedRowKeys.length <= 0) {
            this.messageUtil.warning(this.$t('m.common.tip.select_one_warn'))
            return
          }
          ids = this.rowSelection.selectedRowKeys.join(',')
        } else {
          ids = record.id
        }
        if (button.beforeScript) {
          const _that = this
          const func = handleCreateFunc(button.beforeScript, this)
          const func_result = handleExecFunc(func, {button, ids, objectCode, record}, function(){
            _that.handleDelCallback(button, ids, objectCode, record)
          })
          if(!func_result) return;
        }
        this.handleDelCallback(button, ids, objectCode, record)
      },
      handleDelCallback(button, ids, objectCode, record){
        const that = this
        this.$confirm({
          title: this.$t('m.common.title.delete'),
          content: this.$t('m.common.tip.delete_confirm'),
          onOk: function () {
            let url = that.url.removeData
            that.spinning++
            deleteAction(url, {
              ids: ids,
              boCode: objectCode,
              isFlow: that.isFlow,
              viewCode: that.viewCode,
              openType: button.openType
            }).then((res) => {
              if (res.success) {
                that.messageUtil.success(res.message)
                that.loadData()

                that.$emit("setRefresh", {
                  tableName: that.tableName,
                  type: 'table',
                })

                that.onClearSelected()
                if (button.afterScript) {
                  const func = handleCreateFunc(button.afterScript, that)
                  handleExecFunc(func, {button, record, ids, res})
                }
              } else {
                that.messageUtil.warning(res.message)
              }
            }).finally(() => {
              that.spinning--
            })
          }
        })
      },
      handleReload (button) {
        if (button.beforeScript) {
          const _that = this
          const func = handleCreateFunc(button.beforeScript, this)
          const func_result = handleExecFunc(func, {button}, function(){
            _that.handleReloadCallback(button);
          })
          if(!func_result) return;
        }
        this.handleReloadCallback(button);
      },
      handleReloadCallback(button){
        this.loadData()
        if (button.afterScript) {
          const func = handleCreateFunc(button.afterScript, this)
          handleExecFunc(func, {button})
        }
      },
      handleExportXls(button) {
        const that = this
        getAction(this.url.getExcelMax).then(res => {
          const excelMax = res.result;
          this.$confirm({
            title: this.$t('m.common.title.operate'),
            content: this.$t('m.eform.formDesign.label.excelMaxTip', [excelMax]),
            onOk: function () {
              that.doExportXls(button)
            }
          })
        })
      },
      doExportXls(button){
        const queryValue = this.getQuery();
        if (button.beforeScript) {
          const _that = this
          const func = handleCreateFunc(button.beforeScript, this)
          const func_result = handleExecFunc(func, { button, queryValue }, function(){
            _that.doExportXlsCallback(button, queryValue);
          })
          if (!func_result) return
        }
        this.doExportXlsCallback(button, queryValue);
      },
      doExportXlsCallback(button, queryValue){
        const fileName = this.tableShow.viewName
        if (this.rowSelection && this.rowSelection.selectedRowKeys && this.rowSelection.selectedRowKeys.length > 0) {
          queryValue['selections'] = this.rowSelection.selectedRowKeys
        }

        downFile(this.url.exportXlsUrl + '?viewCode=' + this.viewCode, queryValue, "POST").then((data) => {
          if (!data) {
            this.messageUtil.warning(this.$t('m.eform.formDesign.label.wen-jian-xia-zai-shi-bai'))
            return
          }
          if (typeof window.navigator.msSaveBlob !== 'undefined') {
            window.navigator.msSaveBlob(new Blob([data], { type: 'application/vnd.ms-excel' }), fileName + '.xls')
          } else {
            let url = window.URL.createObjectURL(new Blob([data], { type: 'application/vnd.ms-excel' }))
            let link = document.createElement('a')
            link.style.display = 'none'
            link.href = url
            link.setAttribute('download', fileName + '.xls')
            document.body.appendChild(link)
            link.click()
            document.body.removeChild(link) //下载完成移除元素
            window.URL.revokeObjectURL(url) //释放掉blob对象
          }
        })

        if (button.afterScript) {
          const func = handleCreateFunc(button.afterScript, this)
          handleExecFunc(func, { button })
        }
      },
      handleImportXls(button) {
        if(button.dialogSize === 'tab'){
          button.dialogSize = null
          this.messageUtil.warning(this.$t('m.eform.formDesign.label.gai-gong-neng-bu-zhi-chi-shi-yong-nei-bu-ye-qian-da-kai'))
        }
        if (button.beforeScript) {
          const _that = this
          const func = handleCreateFunc(button.beforeScript, this)
          const func_result = handleExecFunc(func, { button }, function(){
            _that.handleImportXlsCallback(button);
          })
          if (!func_result) return
        }
        this.handleImportXlsCallback(button);
      },
      handleImportXlsCallback(button){
        this.$refs.importDialog.dialogSize = button.dialogSize || 'default';
        this.$refs.importDialog.objectCode = button.objectCode;
        this.$refs.importDialog.afterScript = button.afterScript;
        this.$refs.importDialog.visible = true;
      },
      handleOpenSubView(button, record) {
        const outParameter = button.outParameter
        const viewCode = button.viewCode
        if (!viewCode) {
          this.messageUtil.warning(this.$t('m.eform.formDesign.label.mei-you-pei-zhi-guan-lian-ye-mian'))
          return
        }
        if (!outParameter) {
          // 不一定必须有出参
          // this.messageUtil.warning('没有配置出参信息')
          // return
        }
        if (!record) {
          if (!this.rowSelection || this.rowSelection.selectedRowKeys.length !== 1) {
            this.messageUtil.warning(this.$t('m.common.tip.select_one_warn'))
            return
          }
          record = this.rowSelection.selectionRows[0]
        }
        if (button.beforeScript) {
          const _that = this
          const func = handleCreateFunc(button.beforeScript, this)
          const func_result = handleExecFunc(func, {button, outParameter, viewCode, record}, function(){
            _that.handleOpenSubViewCallback(button, outParameter, viewCode, record)
          })
          if(!func_result) return;
        }
        this.handleOpenSubViewCallback(button, outParameter, viewCode, record)
      },
      handleOpenSubViewCallback(button, outParameter, viewCode, record){
        const outParameterConfig = outParameter ? JSON.parse(outParameter) : []
        let success = true;
        const parameterValue = outParameterConfig.map(item => {
          let value = null;
          if (item.outKey) {
            value = record[item.outKey]
          }
          if (!value && item.defaultValue) {
            value = item.defaultValue
          }
          if (!value && item.isRequired) {
            this.messageUtil.warning(item.customMessage || this.$t('m.eform.formDesign.label.Not_allowed_to_be_empty', [item.parameterKey]))
            success = false
          }
          return {
            colCode: item.parameterKey,
            queryValue: value
          }
        })
        if (!success) {
          return
        }
        if(button.dialogSize === 'tab'){
          button.dialogSize = null
          this.messageUtil.warning(this.$t('m.eform.formDesign.label.gai-gong-neng-bu-zhi-chi-shi-yong-nei-bu-ye-qian-da-kai'))
        }
        this.openSubView(parameterValue, this.$locale(button.buttonName) || this.$t('m.eform.formDesign.label.cha-kan-shu-ju'), viewCode, button.dialogSize)
        if (button.afterScript) {
          const func = handleCreateFunc(button.afterScript, this)
          handleExecFunc(func, {button, record})
        }
      },
      handleExt (button, record) {
        if (!button.openScript) {
          this.messageUtil.warning(this.$t('m.eform.formDesign.label.mei-you-pei-zhi-zi-ding-yi-jiao-ben'))
        }
        if (button.beforeScript) {
          const _that = this
          const func = handleCreateFunc(button.beforeScript, this)
          const func_result = handleExecFunc(func, {button, record}, function (){
            _that.handleExtCallback(button, record)
          })
          if(!func_result) return;
        }
        this.handleExtCallback(button, record)
      },
      handleExtCallback(button, record){
        const openScript = handleCreateFunc(button.openScript, this)
        handleExecFunc(openScript, {button, record})
        if (button.afterScript) {
          const func = handleCreateFunc(button.afterScript, this)
          handleExecFunc(func, {button, record})
        }
      },
      // 新增/修改 成功时，重载列表
      modalFormOk () {
        this.loadData()

        this.$emit("setRefresh", {
          tableName: this.tableName,
          type: 'table',
        })
      },
      render () {
        this.componentFile = (resolve) => ({
          component: import(`@/views/` + this.componentUrl + '.vue'),
          error: error,
          delay: 200,
          timeout: 10000
        })
      },
      openSubViewInSubView(parameterValue, title, viewCode, dialogSize) {
        // TODO 暂不支持子表嵌套弹出
        this.messageUtil.warning(this.$t('m.eform.formDesign.label.zan-bu-zhi-chi-zi-biao-qian-tao-dan-chu'))
      },
      openSubView(parameterValue, title, viewCode, dialogSize) {
        this.subView.dialogSize = dialogSize || 'default';
        this.subView.parameterValue = parameterValue;
        this.subView.viewCode = viewCode;
        this.subView.title = title;
        this.subView.visible = true;
      },
      handleCancelSubView() {
        this.subView.visible = false;
        this.loadData()
      },
      //批量收藏
      handleBatchCollection(button){
        if (!this.rowSelection || this.rowSelection.selectedRowKeys.length <= 0) {
          this.messageUtil.warning(this.$t('m.common.tip.select_one_warn'))
          return
        }
        let processInstanceIdList = []
        let noStarted = false
        let selectionRows = this.rowSelection.selectionRows
        for(let i=0;i<selectionRows.length;i++){
          if(selectionRows[i].bpmStatus == '未启动'){
            noStarted = true
            break;
          }
          processInstanceIdList.push(selectionRows[i].processInstanceId)
        }
        if(noStarted){
          this.messageUtil.warning(this.$t('m.common.tip.notstarted_cannot_batchCollection'))
          return
        }
        let processInstanceIds = processInstanceIdList.join(",")
        if (button.beforeScript) {
          const _that = this
          const func = handleCreateFunc(button.beforeScript, this)
          const func_result = handleExecFunc(func, {button, selectionRows,processInstanceIds}, function (){
            _that.handleBatchCollectionCallback(button, selectionRows,processInstanceIds)
          })
          if(!func_result) return;
        }
        this.handleBatchCollectionCallback(button, selectionRows,processInstanceIds)
      },
      handleBatchCollectionCallback(button,selectionRows,processInstanceIds){
        this.$refs.bpmCollectionDialog.open(processInstanceIds,"")
        if (button.afterScript) {
          const func = handleCreateFunc(button.afterScript, this)
          handleExecFunc(func, {button, selectionRows,processInstanceIds})
        }
      }
    }
  }
</script>
<style lang="less" scoped>
/deep/ .ant-table-thead {
  tr {
    th[colspan="1"] {
      text-align: center;
    }
  }
}
</style>
